import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { spanCalculate } from '@/utils/utils';
import { Button } from 'antd';
import classnames from 'classnames';
import { Modal } from 'gantd';
import type { ModalProps } from 'gantd/lib/modal/interface';
import type { Props as SchemaProps } from 'gantd/lib/schema-form';
import type { Ref } from 'react';
import type { SchemaAllProps } from './FormContent';
import FormContent from './FormContent';
const defaultFooterStyle: React.CSSProperties = { display: 'flex', justifyContent: 'space-between' };

export interface FormModalProps extends SchemaAllProps, ModalProps {
  formSchemaProps?: SchemaProps;
  extraTopContent?: React.ReactNode;
  footerLeftExtra?: React.ReactNode;
  footerRightExtra?: React.ReactNode;
  disabled?: boolean;
  okBtnSolid?: boolean;
  noValidate?: boolean;
  onOk?: (values: object) => void;
  onCancel: () => void;
  customCalculate?: (width: number) => number;
}

const SmartModal = forwardRef((props: FormModalProps, ref: Ref<any>) => {
  const {
    schema,
    uiSchema,
    titleConfig,
    values,
    children,
    extraTopContent,
    formSchemaProps,
    onOk,
    onCancel,
    onSizeChange: customOnSizeChange,
    customCalculate,
    /** 默认的footer左侧插槽 */
    footerLeftExtra,
    /** 默认的footer右侧插槽 */
    footerRightExtra,
    /** 提交按钮是否禁用 */
    disabled,
    /** 提交按钮是否实心 */
    okBtnSolid,
    /** 确定按钮文案 */
    okText,
    /** 取消按钮文案 */
    cancelText,
    /** 弹窗加载状态 */
    confirmLoading,
    /** 外层容器的class */
    wrapClassName,
    /** 忽略表单效验 */
    noValidate,
    ...restProps
  } = props;

  const [span, setSpan] = useState(0);
  const formRef: any = useRef(null);

  const onSizeChange = useCallback(
    (width, height) => {
      const fn = customCalculate || spanCalculate;
      setSpan(fn(width));
      customOnSizeChange && customOnSizeChange(width, height);
    },
    [customCalculate, customOnSizeChange],
  );

  const handleSubmit = useCallback(async () => {
    if (!formRef.current) return;
    const { validateForm, getFieldsValue } = formRef.current;
    if (noValidate) {
      onOk && onOk({ ...values, ...getFieldsValue() });
      return;
    }
    const { errors, values: formValues } = await validateForm();
    if (errors) return;
    onOk && onOk({ ...values, ...formValues });
  }, [values, noValidate, onOk]);

  useImperativeHandle(ref, () => ({
    validateForm: () => {
      if (!formRef.current) return;
      return formRef.current.validateForm();
    },
    resetForm: () => {
      if (!formRef.current) return;
      return formRef.current.resetFields();
    },
    setFieldsValue: (values: any = {}) => {
      if (!formRef.current) return;
      return formRef.current.setFieldsValue(values);
    },
  }));

  const contentExtraProps = useMemo(() => {
    return { uiSchema, titleConfig, span, ...formSchemaProps };
  }, [uiSchema, titleConfig, span, formSchemaProps]);

  const content = useMemo(() => {
    if (!schema) return children;
    return (
      <>
        {extraTopContent}
        <FormContent formRef={formRef} values={values} schema={schema} {...contentExtraProps} />
      </>
    );
  }, [values, schema, children, extraTopContent, contentExtraProps]);

  return (
    <Modal
      bodyStyle={schema && { padding: '3px' }}
      /** 默认节流值 */
      throttle={200}
      maskClosable={false}
      /** 关闭modal的动画效果 */
      transitionName=""
      /** 关闭modal遮罩的动画效果 */
      maskTransitionName=""
      onSizeChange={onSizeChange}
      onCancel={onCancel}
      footer={
        <div style={footerLeftExtra ? defaultFooterStyle : {}}>
          {footerLeftExtra && <div>{footerLeftExtra}</div>}
          <div>
            {footerRightExtra}
            <Button size="small" onClick={onCancel}>
              {cancelText}
            </Button>
            <Button
              size="small"
              type="primary"
              className={okBtnSolid ? 'btn-solid' : ''}
              loading={confirmLoading}
              disabled={disabled}
              onClick={schema ? handleSubmit : onOk}
            >
              {okText}
            </Button>
          </div>
        </div>
      }
      wrapClassName={classnames('gant-layout', wrapClassName)}
      {...restProps}
    >
      {content}
    </Modal>
  );
});
SmartModal.defaultProps = {
  /** 默认回填数据值 */
  values: {},
  formSchemaProps: undefined,
  disabled: false,
  okBtnSolid: false,
  okText: '确定',
  cancelText: '取消',
  footerLeftExtra: '',
  footerRightExtra: '',
};

SmartModal.displayName = 'SmartModal';

export default SmartModal;
